home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 52
/
Amiga Format AFCD52 (Issue 136, May 2000).iso
/
-serious-
/
programming
/
other
/
jikes-1.11
/
src
/
lookup.h
< prev
next >
Wrap
C/C++ Source or Header
|
2000-02-23
|
17KB
|
817 lines
// $Id: lookup.h,v 1.15 2000/01/06 06:46:47 lord Exp $
//
// This software is subject to the terms of the IBM Jikes Compiler
// License Agreement available at the following URL:
// http://www.ibm.com/research/jikes.
// Copyright (C) 1996, 1998, International Business Machines Corporation
// and others. All Rights Reserved.
// You must accept the terms of that agreement to use this software.
//
#ifndef lookup_INCLUDED
#define lookup_INCLUDED
#include "config.h"
#ifdef HAVE_WCHAR_H
# include <wchar.h>
#endif
#include <string.h>
#include <sys/stat.h>
#include <time.h>
#include "tuple.h"
#include "long.h"
#include "double.h"
class Control;
class Symbol;
class PackageSymbol;
class TypeSymbol;
class MethodSymbol;
class MethodShadowSymbol;
class BlockSymbol;
class VariableSymbol;
class VariableShadowSymbol;
class LabelSymbol;
class LiteralSymbol;
class NameSymbol;
class PathSymbol;
class DirectorySymbol;
class FileSymbol;
class ShadowSymbol;
class LiteralValue;
class IntLiteralValue;
class LongLiteralValue;
class FloatLiteralValue;
class DoubleLiteralValue;
class Utf8LiteralValue;
class Utf8LiteralTable;
class NameLookupTable;
class TypeLookupTable;
class LiteralLookupTable;
class AstBinaryExpression;
class AstExpression;
class Hash
{
public:
//
// HASH takes as argument a pointer to a character string
// and its length which it hashes it into a location in the name
// hash table.
//
inline static unsigned Function(wchar_t *head, int len)
{
unsigned long hash_value = head[len >> 1]; // start with center (or unique) letter
wchar_t *tail = &head[len - 1];
for (int i = 0; i < 5 && head < tail; i++)
{
unsigned k = *tail--;
hash_value += ((k << 7) + *head++);
}
return hash_value;
}
//
// Same as above function for a regular "char" string.
//
inline static unsigned Function(char *head, int len)
{
unsigned long hash_value = head[len >> 1]; // start with center (or unique) letter
char *tail = &head[len - 1];
for (int i = 0; i < 5 && head < tail; i++)
{
unsigned k = *tail--;
hash_value += ((k << 7) + *head++);
}
return hash_value;
}
inline static unsigned Function(IEEEfloat value)
{
return value.Word();
}
inline static unsigned Function(IEEEdouble value)
{
unsigned result = value.HighWord() + value.LowWord();
return result;
}
};
class DirectoryEntry
{
public:
DirectoryEntry *next;
char *name;
int length;
DirectoryEntry() : next(NULL),
name(NULL),
length(0),
directory(NULL),
mtime_(0)
{
image = this;
}
virtual ~DirectoryEntry()
{
delete [] name;
}
inline void Initialize(DirectorySymbol *directory_, char *name_, int length_)
{
directory = directory_;
length = length_;
name = new char[length + 1];
memmove(name, name_, length * sizeof(char));
name[length] = U_NULL;
return;
}
inline void Initialize(DirectoryEntry *entry, char *name_, int length_)
{
Initialize(entry -> directory, name_, length_);
}
time_t Mtime();
bool IsDummy() { return this != image; }
//
// See FoldedDirectoryEntry for an explanation of the use of this function
//
virtual DirectoryEntry *Image() { return this; }
protected:
DirectorySymbol *directory;
DirectoryEntry *image;
time_t mtime_;
};
#ifdef WIN32_FILE_SYSTEM
//
// This object is needed only for systems such as Windows NT/95/98 that
// treat filenames in a case-insensitive fashion.
//
class FoldedDirectoryEntry : public DirectoryEntry
{
public:
FoldedDirectoryEntry(DirectoryEntry *image_) { DirectoryEntry::image = image_; }
virtual ~FoldedDirectoryEntry() {}
virtual DirectoryEntry *Image() { return image; }
};
#endif
class SystemTable
{
enum
{
DEFAULT_HASH_SIZE = 13,
MAX_HASH_SIZE = 1021
};
public:
SystemTable(int = DEFAULT_HASH_SIZE);
virtual ~SystemTable();
DirectorySymbol *FindDirectorySymbol(dev_t, ino_t);
void InsertDirectorySymbol(dev_t, ino_t, DirectorySymbol *);
private:
class Element
{
public:
Element(dev_t device_, ino_t inode_, DirectorySymbol *directory_symbol_) : device(device_),
inode(inode_),
directory_symbol(directory_symbol_)
{}
Element *next;
dev_t device;
ino_t inode;
DirectorySymbol *directory_symbol;
};
Tuple<Element *> directories;
Element **base;
int hash_size;
static int primes[];
int prime_index;
int hash(dev_t device, ino_t inode) { return (device + inode) % hash_size; }
void Rehash();
};
class DirectoryTable
{
public:
Tuple<DirectoryEntry *> entry_pool;
DirectoryTable(int estimate = 1024);
~DirectoryTable();
DirectoryEntry *FindEntry(char *, int);
DirectoryEntry *InsertEntry(DirectorySymbol *, char *, int);
#ifdef WIN32_FILE_SYSTEM
//
// See FoldedDirectoryEntry for an explanation of the use of this function
//
DirectoryEntry *FindCaseInsensitiveEntry(char *, int);
void InsertCaseInsensitiveEntry(DirectoryEntry *);
#endif
private:
enum
{
DEFAULT_HASH_SIZE = 1021,
MAX_HASH_SIZE = 8191
};
DirectoryEntry **base;
int hash_size;
static int primes[];
int prime_index;
inline static unsigned Hash(char *head, int len) { return Hash::Function(head, len); }
void Rehash();
};
class Symbol
{
public:
Symbol *next;
enum SymbolKind
{
NONE,
NAME,
PACKAGE,
TYPE, // class or interface
METHOD,
BLOCK,
VARIABLE,
LABEL,
LITERAL,
PATH,
_DIRECTORY,
_FILE,
_num_kinds
};
SymbolKind Kind() { return _kind; }
virtual wchar_t *Name() { return (wchar_t *) NULL; }
virtual size_t NameLength() { return 0; }
virtual NameSymbol *Identity() { return (NameSymbol *) NULL; }
PackageSymbol *PackageCast() { return (PackageSymbol *) (_kind == PACKAGE ? this : NULL); }
TypeSymbol *TypeCast() { return (TypeSymbol *) (_kind == TYPE ? this : NULL); }
MethodSymbol *MethodCast() { return (MethodSymbol *) (_kind == METHOD ? this : NULL); }
BlockSymbol *BlockCast() { return (BlockSymbol *) (_kind == BLOCK ? this : NULL); }
VariableSymbol *VariableCast() { return (VariableSymbol *) (_kind == VARIABLE ? this : NULL); }
LabelSymbol *LabelCast() { return (LabelSymbol *) (_kind == LABEL ? this : NULL); }
LiteralSymbol *LiteralCast() { return (LiteralSymbol *) (_kind == LITERAL ? this : NULL); }
NameSymbol *NameCast() { return (NameSymbol *) (_kind == NAME ? this : NULL); }
PathSymbol *PathCast() { return (PathSymbol *) (_kind == PATH ? this : NULL); }
DirectorySymbol *DirectoryCast() { return (DirectorySymbol *) (_kind == _DIRECTORY ? this : NULL); }
FileSymbol *FileCast() { return (FileSymbol *) (_kind == _FILE ? this : NULL); }
virtual ~Symbol() {}
protected:
SymbolKind _kind;
};
class LiteralValue
{
public:
LiteralValue *next;
int index;
virtual ~LiteralValue() {}
};
class IntLiteralValue : public LiteralValue
{
public:
int value;
virtual ~IntLiteralValue() {}
void Initialize(int value_, int index_)
{
value = value_;
index = index_;
}
};
class LongLiteralValue : public LiteralValue
{
public:
LongInt value;
virtual ~LongLiteralValue() {}
void Initialize(LongInt value_, int index_)
{
value = value_;
index = index_;
}
};
class FloatLiteralValue : public LiteralValue
{
public:
IEEEfloat value;
virtual ~FloatLiteralValue() {}
void Initialize(IEEEfloat value_, int index_)
{
value = value_;
index = index_;
}
};
class DoubleLiteralValue : public LiteralValue
{
public:
IEEEdouble value;
virtual ~DoubleLiteralValue() {}
void Initialize(IEEEdouble value_, int index_)
{
value = value_;
index = index_;
}
};
class Utf8LiteralValue : public LiteralValue
{
public:
char *value;
int length;
Utf8LiteralValue() : value(NULL)
{}
virtual ~Utf8LiteralValue()
{
delete [] value;
}
void Initialize(char *value_, int length_, unsigned hash_address_, int index_)
{
length = length_;
value = new char[length + 1];
memmove(value, value_, length * sizeof(char));
value[length] = U_NULL;
hash_address = hash_address_;
index = index_;
}
private:
friend class Utf8LiteralTable;
unsigned hash_address;
};
class NameSymbol : public Symbol
{
public:
int index;
Utf8LiteralValue *Utf8_literal;
virtual wchar_t *Name() { return name_; }
virtual size_t NameLength() { return length; }
virtual NameSymbol *Identity() { return this; }
char *Utf8Name() { return (char *) (Utf8_literal ? Utf8_literal -> value : NULL); }
int Utf8NameLength() { return (Utf8_literal ? Utf8_literal -> length : 0); }
NameSymbol() : name_(NULL)
{}
virtual ~NameSymbol()
{
delete [] name_;
}
inline void Initialize(wchar_t *str, int length_, unsigned hash_address_, int index_)
{
Symbol::_kind = NAME;
hash_address = hash_address_;
index = index_;
length = length_;
name_ = new wchar_t[length + 1];
memmove(name_, str, length * sizeof(wchar_t));
name_[length] = U_NULL;
Utf8_literal = NULL;
return;
}
private:
friend class NameLookupTable;
wchar_t *name_;
int length;
unsigned hash_address;
};
class NameLookupTable
{
public:
Tuple<NameSymbol *> symbol_pool;
NameLookupTable(int estimate = 16384);
~NameLookupTable();
NameSymbol *FindOrInsertName(wchar_t *, size_t);
private:
enum
{
DEFAULT_HASH_SIZE = 4093,
MAX_HASH_SIZE = 32771
};
NameSymbol **base;
int hash_size;
static int primes[];
int prime_index;
inline static unsigned Hash(wchar_t *head, int len) { return Hash::Function(head, len); }
void Rehash();
};
class TypeLookupTable
{
public:
TypeLookupTable(int estimate = 16384);
~TypeLookupTable();
TypeSymbol *FindType(char *, int);
void InsertType(TypeSymbol *);
void SetEmpty();
private:
Tuple<TypeSymbol *> symbol_pool;
enum
{
DEFAULT_HASH_SIZE = 4093,
MAX_HASH_SIZE = 32771
};
TypeSymbol **base;
int hash_size;
static int primes[];
int prime_index;
inline static unsigned Hash(char *head, int len) { return Hash::Function(head, len); }
void Rehash();
};
class LiteralSymbol : public Symbol
{
public:
LiteralValue *value;
virtual wchar_t *Name() { return name_; }
virtual size_t NameLength() { return length; }
virtual NameSymbol *Identity() { return (NameSymbol *) NULL; }
LiteralSymbol() : name_(NULL)
{}
virtual ~LiteralSymbol()
{
delete [] name_;
}
void Initialize(wchar_t *str, unsigned hash_address_, int length_)
{
Symbol::_kind = LITERAL;
hash_address = hash_address_;
length = length_;
name_ = new wchar_t[length + 1];
memmove(name_, str, length * sizeof(wchar_t));
name_[length] = U_NULL;
value = NULL;
}
private:
friend class LiteralLookupTable;
wchar_t *name_;
int length;
unsigned hash_address;
};
class LiteralLookupTable
{
public:
Tuple<LiteralSymbol *> symbol_pool;
LiteralLookupTable();
~LiteralLookupTable();
LiteralSymbol *FindOrInsertLiteral(wchar_t *, size_t);
private:
enum
{
DEFAULT_HASH_SIZE = 1021,
MAX_HASH_SIZE = 8191
};
LiteralSymbol **base;
int hash_size;
static int primes[];
int prime_index;
inline static unsigned Hash(wchar_t *head, int len) { return Hash::Function(head, len); }
void Rehash();
};
class IntLiteralTable
{
public:
Tuple<IntLiteralValue *> symbol_pool;
IntLiteralTable(LiteralValue *);
~IntLiteralTable();
LiteralValue *FindOrInsertNull()
{
return FindOrInsert(0);
}
LiteralValue *FindOrInsertChar(LiteralSymbol *);
LiteralValue *FindOrInsertInt(LiteralSymbol *);
LiteralValue *FindOrInsertHexInt(LiteralSymbol *);
LiteralValue *FindOrInsertOctalInt(LiteralSymbol *);
LiteralValue *FindOrInsertNegativeInt(LiteralSymbol *);
IntLiteralValue *FindOrInsert(int);
IntLiteralValue *Find(int);
#ifdef TEST
//
// To prevent arithmentic conversion to allow illegal calls inadvertently.
// Since the return type is wrong, compilation will fail !
//
void FindOrInsert(LongInt) {}
void FindOrInsert(float) {}
void FindOrInsert(double) {}
#endif
private:
enum
{
DEFAULT_HASH_SIZE = 4093,
MAX_HASH_SIZE = 32771
};
IntLiteralValue **base;
int hash_size;
static int primes[];
int prime_index;
static int int32_limit;
LiteralValue *bad_value;
void Rehash();
};
class LongLiteralTable
{
public:
Tuple<LongLiteralValue *> symbol_pool;
LongLiteralTable(LiteralValue *);
~LongLiteralTable();
LiteralValue *FindOrInsertLong(LiteralSymbol *);
LiteralValue *FindOrInsertHexLong(LiteralSymbol *);
LiteralValue *FindOrInsertOctalLong(LiteralSymbol *);
LiteralValue *FindOrInsertNegativeLong(LiteralSymbol *);
LongLiteralValue *FindOrInsert(LongInt);
#ifdef TEST
//
// To prevent arithmentic conversion to allow illegal calls inadvertently.
//
void FindOrInsert(int) {}
void FindOrInsert(float) {}
void FindOrInsert(double) {}
#endif
private:
enum
{
DEFAULT_HASH_SIZE = 1021,
MAX_HASH_SIZE = 8191
};
LongLiteralValue **base;
int hash_size;
static int primes[];
int prime_index;
static LongInt int64_limit;
LiteralValue *bad_value;
void Rehash();
};
class FloatLiteralTable
{
public:
Tuple<FloatLiteralValue *> symbol_pool;
FloatLiteralTable(LiteralValue *);
~FloatLiteralTable();
LiteralValue *FindOrInsertFloat(LiteralSymbol *);
FloatLiteralValue *FindOrInsert(IEEEfloat);
#ifdef TEST
//
// To prevent arithmentic conversion to allow illegal calls inadvertently.
//
void FindOrInsert(int) {}
void FindOrInsert(LongInt) {}
void FindOrInsert(double) {}
#endif
private:
enum
{
DEFAULT_HASH_SIZE = 1021,
MAX_HASH_SIZE = 8191
};
FloatLiteralValue **base;
int hash_size;
static int primes[];
int prime_index;
LiteralValue *bad_value;
inline static unsigned Hash(IEEEfloat value) { return Hash::Function(value); }
void Rehash();
};
class DoubleLiteralTable
{
public:
Tuple<DoubleLiteralValue *> symbol_pool;
DoubleLiteralTable(LiteralValue *);
~DoubleLiteralTable();
LiteralValue *FindOrInsertDouble(LiteralSymbol *);
DoubleLiteralValue *FindOrInsert(IEEEdouble);
#ifdef TEST
//
// To prevent arithmentic conversion to allow illegal calls inadvertently.
//
void FindOrInsert(int) {}
void FindOrInsert(LongInt) {}
void FindOrInsert(float) {}
#endif
private:
enum
{
DEFAULT_HASH_SIZE = 1021,
MAX_HASH_SIZE = 8191
};
DoubleLiteralValue **base;
int hash_size;
static int primes[];
int prime_index;
LiteralValue *bad_value;
inline static unsigned Hash(IEEEdouble value) { return Hash::Function(value); }
void Rehash();
};
class Utf8LiteralTable
{
public:
Tuple<Utf8LiteralValue *> symbol_pool;
Utf8LiteralTable(LiteralValue *);
~Utf8LiteralTable();
LiteralValue *FindOrInsertString(LiteralSymbol *);
Utf8LiteralValue *FindOrInsert(char *, int);
Utf8LiteralValue *FindOrInsert(wchar_t);
void CheckStringConstant(AstExpression *expr);
private:
Tuple<AstExpression *> *expr;
void EvaluateConstant(AstExpression *, int, int);
bool IsConstant(AstExpression *);
enum
{
DEFAULT_HASH_SIZE = 4093,
MAX_HASH_SIZE = 32771
};
Utf8LiteralValue **base;
int hash_size;
static int primes[];
int prime_index;
LiteralValue *bad_value;
inline static unsigned Hash(char *head, int len) { return Hash::Function(head, len); }
void Rehash();
};
#endif